#include "gui.h"
extern TFT_t DEV;

extern const unsigned char bagnum[];
TickType_t RoundRectTest(TFT_t * dev, int width, int height,uint16_t color) {
	TickType_t startTick, endTick, diffTick;
	startTick = xTaskGetTickCount();

	uint16_t limit = width;
	if (width > height) limit = height;

	for(int i=5;i<limit;i=i+5) {
		if (i > (limit-i-1) ) break;
		//ESP_LOGI(__FUNCTION__, "i=%d, width-i-1=%d",i, width-i-1);
		lcdDrawRoundRect(dev, i, i, (width-i-1), (height-i-1), 10, color);
	}

	endTick = xTaskGetTickCount();
	diffTick = endTick - startTick;
	ESP_LOGI(__FUNCTION__, "elapsed time[ms]:%d",diffTick*portTICK_RATE_MS);
	return diffTick;
}

TickType_t JPEGshow(TFT_t * dev, char * file, int width, int height,int _cols,int _rows) {
	TickType_t startTick, endTick, diffTick;
	startTick = xTaskGetTickCount();

	pixel_s **pixels;
	uint16_t imageWidth;//图片宽度
	uint16_t imageHeight;//图片高度
	esp_err_t err = decode_image(&pixels, file, width, height, &imageWidth, &imageHeight);
	ESP_LOGI(__FUNCTION__, "decode_image err=%d imageWidth=%d imageHeight=%d", err, imageWidth, imageHeight);
	if (err == ESP_OK) {

		uint16_t _width = width;//135
	

		uint16_t _height = height;
	
		uint16_t *colors = (uint16_t*)malloc(sizeof(uint16_t) * _width);



		for(int y = 0; y < _height; y++){
			for(int x = 0;x < _width; x++){
				pixel_s pixel = pixels[y][x];
				colors[x] = rgb565_conv(pixel.red, pixel.green, pixel.blue);
			}
			lcdDrawMultiPixels(dev, _cols, y+_rows, _width, colors);
			//vTaskDelay(1);
		}

		free(colors);
		release_image(&pixels, width, height);
		ESP_LOGD(__FUNCTION__, "Finish");
	}

	endTick = xTaskGetTickCount();
	diffTick = endTick - startTick;
	ESP_LOGI(__FUNCTION__, "elapsed time[ms]:%d",diffTick*portTICK_RATE_MS);
	return diffTick;
}

TickType_t JPEGTest(TFT_t * dev, char * file, int width, int height) {
	TickType_t startTick, endTick, diffTick;
	startTick = xTaskGetTickCount();

	lcdFillScreen(dev, BLACK);//清屏


	pixel_s **pixels;
	uint16_t imageWidth;//图片宽度
	uint16_t imageHeight;//图片高度
	esp_err_t err = decode_image(&pixels, file, width, height, &imageWidth, &imageHeight);
	ESP_LOGI(__FUNCTION__, "decode_image err=%d imageWidth=%d imageHeight=%d", err, imageWidth, imageHeight);
	if (err == ESP_OK) {

		uint16_t _width = width;//135
		uint16_t _cols = 0;
		if (width > imageWidth) {//
			_width = imageWidth;
			_cols = (width - imageWidth) / 2;
		}
		ESP_LOGD(__FUNCTION__, "_width=%d _cols=%d", _width, _cols);

		uint16_t _height = height;
		uint16_t _rows = 0;
		if (height > imageHeight) {
			_height = imageHeight;
			_rows = (height - imageHeight) / 2;
		}
		ESP_LOGD(__FUNCTION__, "_height=%d _rows=%d", _height, _rows);
		uint16_t *colors = (uint16_t*)malloc(sizeof(uint16_t) * _width);

#if 0
		for(int y = 0; y < _height; y++){
			for(int x = 0;x < _width; x++){
				pixel_s pixel = pixels[y][x];
				uint16_t color = rgb565_conv(pixel.red, pixel.green, pixel.blue);
				lcdDrawPixel(dev, x+_cols, y+_rows, color);
			}
			vTaskDelay(1);
		}
#endif

		for(int y = 0; y < _height; y++){
			for(int x = 0;x < _width; x++){
				pixel_s pixel = pixels[y][x];
				colors[x] = rgb565_conv(pixel.red, pixel.green, pixel.blue);
			}
			lcdDrawMultiPixels(dev, _cols, y+_rows, _width, colors);
			//vTaskDelay(1);
		}

		free(colors);
		release_image(&pixels, width, height);
		ESP_LOGD(__FUNCTION__, "Finish");
	}

	endTick = xTaskGetTickCount();
	diffTick = endTick - startTick;
	ESP_LOGI(__FUNCTION__, "elapsed time[ms]:%d",diffTick*portTICK_RATE_MS);
	return diffTick;
}

TickType_t PNGTest(TFT_t * dev, char * file, int width, int height,int x1,int y1) {

		//TickType_t startTick, endTick, diffTick;
		//startTick = xTaskGetTickCount();
		// open PNG file
		FILE* fp = fopen(file, "rb");
		if (fp == NULL) {
				ESP_LOGW(__FUNCTION__, "File not found [%s]", file);
				return 0;
		}

		char buf[1024];
		size_t remain = 0;
		int len;

		pngle_t *pngle = pngle_new(width, height);

		pngle_set_init_callback(pngle, png_init);
		pngle_set_draw_callback(pngle, png_draw);
		pngle_set_done_callback(pngle, png_finish);

		double display_gamma = 2.2;
		pngle_set_display_gamma(pngle, display_gamma);

		while (!feof(fp)) {
				if (remain >= sizeof(buf)) {
						ESP_LOGE(__FUNCTION__, "Buffer exceeded");
						while(1) vTaskDelay(1);
				}

				len = fread(buf + remain, 1, sizeof(buf) - remain, fp);
				if (len <= 0) {
						//printf("EOF\n");
						break;
				}

				int fed = pngle_feed(pngle, buf, remain + len);
				if (fed < 0) {
						ESP_LOGE(__FUNCTION__, "ERROR; %s", pngle_error(pngle));
						while(1) vTaskDelay(1);
				}

				remain = remain + len - fed;
				if (remain > 0) memmove(buf, buf + fed, remain);
		}

		fclose(fp);

		uint16_t _width = width;
	

	//	ESP_LOGD(__FUNCTION__, "_width=%d _cols=%d", _width, _cols);

		uint16_t _height = height;


	//	ESP_LOGD(__FUNCTION__, "_height=%d _rows=%d", _height, _rows);
		uint8_t *colors = malloc(sizeof(uint16_t) * _width);

		uint16_t *data = (uint16_t*)malloc(2 * width*height);
		memset(data,0xff,2 * width*height);
		for(int y = 0; y < _height; y++){
				for(int x = 0;x < _width; x++){
						pixel_png pixel = pngle->pixels[y][x];
						uint16_t color = rgb565_conv(pixel.blue, pixel.green,pixel.red );
								*(colors+x*2) = (color >> 8) & 0xFF;
								*(colors+x*2+1)= color & 0xFF;
					//	*(data+y*width+x)= rgb565_conv(pixel.red, pixel.green, pixel.blue);
						//colors[x] = rgb565_conv(pixel.blue, pixel.green, pixel.red);
						//
						//colors[x] = ~color;
				}

			//lcdDrawMultiPixels(dev, _cols, y+_rows, _width, colors);
				memcpy(data+y*width, colors, width*2);
		}

		lcd_fastDraw_xy(dev,x1,y1,width,height,(uint8_t *)data);
		free(colors);
		free(data);
		pngle_destroy(pngle, width, height);
	//	endTick = xTaskGetTickCount();
	//	diffTick = endTick - startTick;
		//ESP_LOGI(__FUNCTION__, "elapsed time[ms]:%d",diffTick*portTICK_RATE_MS);
		//return diffTick;
		return 0;
}

TickType_t PNG_SHOW(char * file, int width, int height,int x1,int y1,uint8_t *data,uint8_t w) {


		FILE* fp = fopen(file, "rb");
		if (fp == NULL) {
				ESP_LOGW(__FUNCTION__, "File not found [%s]", file);
				return 0;
		}
		char buf[1024];
		size_t remain = 0;
		int len;
		pngle_t *pngle = pngle_new(width, height);

		pngle_set_init_callback(pngle, png_init);
		pngle_set_draw_callback(pngle, png_draw);
		pngle_set_done_callback(pngle, png_finish);

		double display_gamma = 2.2;
		pngle_set_display_gamma(pngle, display_gamma);

		while (!feof(fp)) {
				if (remain >= sizeof(buf)) {
						ESP_LOGE(__FUNCTION__, "Buffer exceeded");
						while(1) vTaskDelay(1);
				}

				len = fread(buf + remain, 1, sizeof(buf) - remain, fp);
				if (len <= 0) {
						//printf("EOF\n");
						break;
				}

				int fed = pngle_feed(pngle, buf, remain + len);
				if (fed < 0) {
						ESP_LOGE(__FUNCTION__, "ERROR; %s", pngle_error(pngle));
						while(1) vTaskDelay(1);
				}

				remain = remain + len - fed;
				if (remain > 0) memmove(buf, buf + fed, remain);
		}

		fclose(fp);

		uint16_t _width = width;
	
		uint16_t _height = height;
	
		for(int y = 0; y < _height; y++){
				for(int x = 0;x < _width; x++){
						pixel_png pixel = pngle->pixels[y][x];
						uint16_t color = rgb565_conv(pixel.blue, pixel.green,pixel.red );
								if(color!=BLACK)
								{
								*(data+(y+y1)*2*w+(x+x1)*2) = (color >> 8) & 0xFF;
								*(data+(y+y1)*2*w+(x+x1)*2+1)= color & 0xFF;
								}

				}
		}

		pngle_destroy(pngle, width, height);
		return 0;
}

void png_init(pngle_t *pngle, uint32_t w, uint32_t h)
{
		ESP_LOGD(__FUNCTION__, "png_init w=%d h=%d", w, h);
		ESP_LOGD(__FUNCTION__, "screenWidth=%d screenHeight=%d", pngle->screenWidth, pngle->screenHeight);
		pngle->imageWidth = w;
		pngle->imageHeight = h;
		pngle->reduction = false;
		pngle->scale_factor = 1.0;

		// Calculate Reduction
		if (pngle->screenWidth < pngle->imageWidth || pngle->screenHeight < pngle->imageHeight) {
				pngle->reduction = true;
				double factorWidth = (double)pngle->screenWidth / (double)pngle->imageWidth;
				double factorHeight = (double)pngle->screenHeight / (double)pngle->imageHeight;
				pngle->scale_factor = factorWidth;
				if (factorHeight < factorWidth) pngle->scale_factor = factorHeight;
				pngle->imageWidth = pngle->imageWidth * pngle->scale_factor;
				pngle->imageHeight = pngle->imageHeight * pngle->scale_factor;
		}
		ESP_LOGD(__FUNCTION__, "reduction=%d scale_factor=%f", pngle->reduction, pngle->scale_factor);
		ESP_LOGD(__FUNCTION__, "imageWidth=%d imageHeight=%d", pngle->imageWidth, pngle->imageHeight);

}

void png_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
		ESP_LOGD(__FUNCTION__, "png_draw x=%d y=%d w=%d h=%d", x,y,w,h);
#if 0
		uint8_t r = rgba[0];
		uint8_t g = rgba[1];
		uint8_t b = rgba[2];
#endif

		// image reduction
		uint32_t _x = x;
		uint32_t _y = y;
		if (pngle->reduction) {
				_x = x * pngle->scale_factor;
				_y = y * pngle->scale_factor;
		}
		if (_y < pngle->screenHeight && _x < pngle->screenWidth) {
				pngle->pixels[_y][_x].red = rgba[0];
				pngle->pixels[_y][_x].green = rgba[1];
				pngle->pixels[_y][_x].blue = rgba[2];
		}

}

void png_finish(pngle_t *pngle) {
		ESP_LOGD(__FUNCTION__, "png_finish");
}
void jindu(int m, uint16_t color)
{
	int n;
	n=150*m/100-2;
	lcdDrawRect(&DEV, 50, 50, 200, 60, WHITE);
	if(n>0)
	{
		lcdDrawFillRect(&DEV, 52,52, 50+n, 58, color);
	}
	
}

void show_rate(void (*fun)(),uint8_t rate,uint16_t color)
{
	
	fun();
	lcdDrawFillRect(&DEV, 0, 70, 239, 134,BLACK);
	jindu(rate,color);
}
void LCD_ShowChinese(TFT_t * dev,uint16_t x, uint16_t y, uint8_t index, uint16_t color,const unsigned char * bin)	
{  
	unsigned char i,j;
	unsigned char *temp,size1;
	temp=(unsigned char *)bin;

  size1=32;//Ò»¸öºº×ÖËùÕ¼µÄ×Ö½Ú
	temp+=index*size1;//Ð´ÈëµÄÆðÊ¼Î»ÖÃ
	for(j=0;j<32;j++)
	{
		for(i=0;i<8;i++)
		{
		 	if((*temp&(1<<i))!=0)//´ÓÊý¾ÝµÄµÍÎ»¿ªÊ¼¶Á
			{
				lcdDrawPixel(dev, j%16+x,y+((j>15)?i+8:i), color);
			}
			else
			{
				
			}
		}
		temp++;
	 }
}

void LCD_ShowNum(TFT_t * dev,uint16_t x, uint16_t y, uint8_t index, uint16_t color)	
{  
	unsigned char i,j;
	unsigned char *temp,size1;
	temp=(unsigned char *)bagnum;

  size1=192;//Ò»¸öºº×ÖËùÕ¼µÄ×Ö½Ú
	temp+=index*size1;//Ð´ÈëµÄÆðÊ¼Î»ÖÃ
	for(j=0;j<192;j++)
	{
		for(i=0;i<8;i++)
		{
		 	if((*temp&(1<<i))!=0)//´ÓÊý¾ÝµÄµÍÎ»¿ªÊ¼¶Á
			{
				lcdDrawPixel(dev, j%24+x,y+j/24*8+i, color);
			}
			else
			{
				
			}
		}
		temp++;
	 }
}

void LCD_Show_MoreNum(TFT_t * dev,uint16_t x, uint16_t y, uint16_t index, uint16_t color,uint8_t flag)	
{
	uint8_t len=1;
	uint16_t a=index;
	while(a/=10)
	{
		len++;
	}
	for(uint8_t i=0;i<len;i++)
	{
		a=index%10;
		if(flag)
		lcdDrawNum(dev,x+(len-i-1)*24,y,a,color);
		else
		{
		LCD_ShowNum(dev,x+(len-i-1)*24,y,a,color);
		}
		
		index/=10;
	}

}
void lcdShowClock(TFT_t * dev,uint16_t x, uint16_t y, uint16_t index, uint16_t color)
{
	if(index<10)
	{
		lcdDrawNum(dev,x,y,0,color);
		lcdDrawNum(dev,x+24,y,index,color);
	}
	else
	{
		LCD_Show_MoreNum(dev, x,  y, index,  color,1);
	}
	

}